package com.annual.system.service.impl;


import cn.hutool.core.lang.UUID;
import com.annual.common.config.WxPayConfig;
import com.annual.common.core.domain.entity.SysUser;
import com.annual.common.exception.ServiceException;
import com.annual.common.utils.Assert;
import com.annual.system.domain.EnterpriseBusiness;
import com.annual.system.domain.Order;
import com.annual.system.dto.enterpriseBusiness.ResAppPlanOrderDto;
import com.annual.system.dto.order.ReqOrderPayListDto;
import com.annual.system.dto.order.ResOrderPayListDto;
import com.annual.system.dto.order.ResOrderRefundListDto;
import com.annual.system.mapper.OrderMapper;
import com.annual.system.service.*;
import com.annual.system.wechat.PayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 订单表
 * </p>
 *
 * @author ywb
 * @since 2024-12-02
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Resource
    private PayUtil payUtil;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IEnterpriseBusinessService enterpriseBusinessService;

    @Override
    public void updateOrderstatus(String outTradeNo, Integer status) {
        LambdaUpdateWrapper<Order> wrapper = Wrappers.lambdaUpdate(Order.class);
        wrapper.eq(Order::getOutTradeNo,outTradeNo);
        wrapper.set(Order::getStatus,status);
        if(status.equals(2)){
            wrapper.set(Order::getPayTime,LocalDateTime.now());
        }
        update(wrapper);
    }

    @Override
    public Map<String,Object> placeOrder(Long orderId) {
        //查询这个单子是否成功支付
        int count = count(Wrappers.lambdaQuery(Order.class)
                .eq(Order::getOrderId,orderId)
                .eq(Order::getOrderType,1)
                .eq(Order::getStatus,2));
        if(count > 0){
            throw new ServiceException("当前业务已支付成功，无需重新支付！");
        }
        Order order = getById(orderId);
        Assert.notNull(order,"未找到订单");
        EnterpriseBusiness enterpriseBusiness = enterpriseBusinessService.getById(order.getEnterpriseBusinessId());
        Assert.notNull(enterpriseBusiness,"未找到当前业务");
        SysUser sysUser = sysUserService.selectUserById(enterpriseBusiness.getUserId());
        Assert.notNull(sysUser,"未找到用户");
        //去下单
        return payUtil.jsapi(order,sysUser.getOpenId());
    }

    @Override
    public boolean callback(Map<String, String> map) {
        String attach = map.get("attach");
        String transactionId = map.get("transaction_id");
        String resultCode = map.get("result_code");
        Order order = getById(attach);
        if (order.getStatus() == 1) {
            order.setSerialNo(transactionId);
            if (resultCode.equalsIgnoreCase("SUCCESS")) {
                order.setStatus(2);
            } else {
                order.setStatus(6);//支付失败
            }
            order.setPayTime(LocalDateTime.now());
            order.updateById();
            return true;
        }
        return false;
    }

    @Override
    public Order getLastOrder(Long enterpriseBusinessId) {
        return getOne(Wrappers.lambdaQuery(Order.class)
                .eq(Order::getEnterpriseBusinessId,enterpriseBusinessId)
                .eq(Order::getOrderType,1)
                .orderByDesc(Order::getCreateTime)
                .last(" limit 1"));
    }

    @Override
    public List<ResOrderPayListDto> payList(ReqOrderPayListDto req) {
        List<ResOrderPayListDto> data =  baseMapper.payList(req);
        for (ResOrderPayListDto datum : data) {
            //datum.setStatus(getStatusName(datum.getStatus()));
            datum.setType(enterpriseBusinessService.getTypeName(datum.getType()));
        }
        return data;
    }

    @Override
    public String getStatusName(Object status){
        if(status == null){
            return "未知";
        }
        String statusStr = status.toString();
        if(statusStr.equals("1")){
            return "待付款";
        }
        if(statusStr.equals("2")){
            return "已付款";
        }
        if(statusStr.equals("3")){
            return "已处理";
        }
        if(statusStr.equals("4")){
            return "已退款";
        }
        if(statusStr.equals("5")){
            return "已关闭";
        }
        return "未知";
    }

    //https://github.com/wechatpay-apiv3/wechatpay-java/blob/main/service/src/example/java/com/wechat/pay/java/service/refund/RefundServiceExample.java
    @Override
    public void refund(Long orderId) {
        Order order = getById(orderId);
        Assert.notNull(order,"未查到订单");
        Assert.isTrue(!order.getStatus().equals(2),"该订单未支付成功，不能退款");
        Assert.isTrue(order.getStatus().equals(4),"该订单已全额退款，不能退款");
        CreateRequest request = payUtil.refund(order);
        if(request != null){
            //添加订单
            Order refundOrder = new Order();
            refundOrder.setOrderType(2);
            refundOrder.setCreateTime(LocalDateTime.now());
            refundOrder.setUserId(order.getUserId());
            refundOrder.setEnterpriseBusinessId(order.getEnterpriseBusinessId());
            refundOrder.setType(order.getType());
            refundOrder.setFee(order.getFee());
            refundOrder.setPrice(order.getPrice());
            refundOrder.setStatus(4);
            refundOrder.setOutTradeNo(order.getOutTradeNo());
            refundOrder.setPayTime(order.getPayTime());
            refundOrder.setOutRefundNo(request.getOutRefundNo());
            refundOrder.setRefundTime(LocalDateTime.now());
            refundOrder.setRefundOrderId(order.getOrderId());
            refundOrder.insert();
            order.setRefundAmount(order.getFee());
            order.setStatus(4);
            order.updateById();
        }
    }

    @Override
    public List<ResOrderRefundListDto> refundList(ReqOrderPayListDto req) {
        List<ResOrderRefundListDto> data =  baseMapper.refundList(req);
//        for (ResOrderRefundListDto datum : data) {
//            datum.setStatus(getStatusName(datum.getStatus()));
//        }
        return data;
    }


}
